package com.rzjm.api.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rzjm.api.dao.DeviceRangeDao;
import com.rzjm.api.dao.DeviceRangeResultDao;
import com.rzjm.api.dao.ShopDao;
import com.rzjm.api.entity.*;
import com.rzjm.api.entity.dto.Cone;
import com.rzjm.api.entity.dto.Cylinder;
import com.rzjm.api.exception.TransactionalException;
import com.rzjm.api.service.DeviceRangeService;
import com.rzjm.api.util.MathUtil;
import com.rzjm.api.util.OssUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

@Service
public class DeviceRangeServiceImpl extends BaseServiceImpl<DeviceRangeDao, DeviceRange> implements DeviceRangeService {

    @Resource
    private DeviceRangeDao deviceRangeDao;
    @Resource
    private DeviceRangeResultDao deviceRangeResultDao;
    @Resource
    private ShopDao shopDao;

    @Resource
    protected RedisTemplate<String, Object> redisTemplate;

    @Override
    @Transactional
    public int initDevice(DeviceRange deviceRange) {
        int num = 0;
        int ret = 0;
        try{

            //创建圆柱体对象
            Cylinder volu = new Cylinder();
            //给半径和高赋值
            volu.setRad(deviceRange.getStoreDiameter() / 2);
            volu.setHeight(deviceRange.getCylinderHeight());
            //输出
            System.out.println("底面半径 = " + volu.getRad());
            System.out.println("圆柱的高 = " + volu.getHeight());
            System.out.println("圆柱");
            //调用方法直接输出底面积
            volu.area();
            double volumeCylinder = volu.volume();
            //调用方法输出圆柱体体积
            System.out.println("圆柱体体积 = " + volumeCylinder);
            deviceRange.setMaxCylinderVolume(volumeCylinder);

            Cone cone = new Cone();
            cone.setIsEllipse(deviceRange.getIsEllipse());
            volu.setLongHalf(0);
            volu.setShortHalf(0);
            deviceRange.setLongHalfShaft(0d);
            deviceRange.setShortHalfShaft(0d);
            if(deviceRange.getIsEllipse() == 1){
                volu.setLongHalf(deviceRange.getLongHalfShaft());
                volu.setShortHalf(deviceRange.getShortHalfShaft());
            }
            cone.setRad(deviceRange.getStoreDiameter() / 2);
            cone.setHeight(deviceRange.getConeHeight());

            double volumeCone = cone.volume();
            System.out.println("圆锥体体积 = " + volumeCone);

            deviceRange.setMaxConeVolume(volumeCone);

            deviceRange.setMaxVolume(volumeCylinder + volumeCone);

            deviceRange.setStoreHeight(deviceRange.getConeHeight() + deviceRange.getCylinderHeight());

            deviceRange.setStoreState(0);
            deviceRange.setSort(1);
            deviceRange.setHeightDifference(1d);
            deviceRange.setTemperature("0");
            deviceRange.setHumidity("0");
            deviceRange.setErrorAngle(0);
            deviceRange.setErrorHeight(4d);
            deviceRange.setExtendRatio(0d);
            deviceRange.setTotalWeight(0d);
            deviceRange.setAvgHeight(0d);
            deviceRange.setLastBevel(0d);
            deviceRange.setShapeType(0);
            deviceRange.setEmptyHeight(0.5);
            deviceRange.setPlotRatio(800);
            deviceRange.setMaxRange(8d);
            deviceRange.setCreateTime(new Date());
            deviceRange.setLastVolumeNew(0d);
            deviceRange.setLastVolume(0d);
            deviceRange.setLastHeightVolume(0d);
            deviceRange.setConcaveConvexVolume(0d);
            deviceRange.setLastEmptyVolume(0d);
            deviceRange.setMaxAngle(90d);
            /**
             * 凸起时 调整的重量
             */
            deviceRange.setBulgeKg(0d);

            /**
             * 凹下时 调整的重量
             */
            deviceRange.setConcaveKg(0d);
            if(deviceRange.getDeviceType() == 0){
                deviceRange.setConcaveKg(-5000d);
            }
            /**
             * 筒仓直径  deviceRange.getStoreDiameter()
             */
            //圆锥的 直角的角度
            double coneAngle = MathUtil.getAngleByHeightAndAngle(deviceRange.getConeHeight(),deviceRange.getStoreDiameter()/2);

            //圆锥的 直角的角度 * 2 = 完整的角度
            deviceRange.setConeAngle(coneAngle * 2);

            //斜边长度
            double coneHypotenuse = MathUtil.getHypotenuseFromLength(deviceRange.getConeHeight(),deviceRange.getStoreDiameter()/2);
            deviceRange.setConeHypotenuse(coneHypotenuse);
            deviceRange.setConcaveConvexVolume(0d);
            deviceRange.setLastHeightVolume(0d);

            ret = deviceRangeDao.insert(deviceRange);
            if(ret <= 0){
                throw new TransactionalException("devicesMapper updateById error");
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new TransactionalException("devicesMapper insert error");
        }
        return num;
    }

    @Override
    public List<DeviceRange> getRangeListByShopId(User user, int shopId,int device_type,int pageIndex,int pageSize) {
        QueryWrapper<DeviceRange> qw = new QueryWrapper<>();
        qw.eq("shop_id",shopId);
        qw.eq("device_type",device_type);
        qw.orderByAsc("device_name");
        qw.orderByAsc("sort");
        List<DeviceRange> list = deviceRangeDao.getPageEntityList(qw,pageIndex,pageSize);
        if(CollUtil.isNotEmpty(list)){
            for (DeviceRange range : list){

                if(range.getHumidity() == null
                        || (range.getHumidity()!= null && (range.getHumidity().equals("0")
                        || range.getHumidity().equals("00")))){
                    double temp = Double.parseDouble(range.getTemperature());
                    range.setTemperature(MathUtil.getDoubleUp(temp * 0.1)+"");
                }


                QueryWrapper<DeviceRangeResult> qwResult = new QueryWrapper<>();
                qwResult.eq("device_id",range.getId());
                if(user.getIsTest() == 0){
                    qwResult.eq("is_test", user.getIsTest()!= null ? user.getIsTest() : 0);
                }

                if(range.getLastVolumeNew() < 0){
                    range.setLastVolumeNew(0d);
                }
                qwResult.orderByDesc("create_time");
                qwResult.last("limit 1");
                DeviceRangeResult lastResult = deviceRangeResultDao.selectOne(qwResult);
                if(lastResult != null){
                    range.setLastResult(lastResult);
                    range.setLastComputeTime(lastResult.getCreateTime());

//                    if(lastResult.getHumidity() == null
//                            || (lastResult.getHumidity()!= null && (lastResult.getHumidity().equals("0")
//                            || lastResult.getHumidity().equals("00")))){
//                        double temp = Double.parseDouble(lastResult.getTemperature());
//                        range.setTemperature(MathUtil.getDoubleUp(temp * 0.1)+"");
//                    }

//                    if(StrUtil.isNotEmpty(lastResult.getTemperature())){
//                        double temp = Double.parseDouble(lastResult.getTemperature());
//                        if(temp > 100){
//                            range.setTemperature(MathUtil.getDoubleUp(temp * 0.1)+"");
//                        }else{
//                            range.setTemperature(temp+"");
//                        }
//                    }

                    if(lastResult.getWeight() != null){
                        range.setTotalWeightDun(MathUtil.getDoubleUp(lastResult.getWeight() / 1000));
                        range.setTotalWeight(MathUtil.getDoubleUp(lastResult.getWeight() / 1000));

                        if(lastResult.getWeightNew()!= null && lastResult.getWeightNew()> 0){
                            range.setTotalWeightDunNew(MathUtil.getDoubleUp((lastResult.getWeight() + lastResult.getWeightNew()) / 1000));
                        }
                    }

                    if(range.getDeviceType() == 1){
                        range.setMeasureSeconds(5 * 1000);
                    }
                }

                Shop shop = shopDao.selectById(range.getShopId());
                if(shop!=null){
                    range.setShopName(shop.getShopName());
                }
            }
        }
        return list;
    }

    @Override
    public DeviceRange getDeviceInfoByNum(String device_num) {
        QueryWrapper<DeviceRange> qw = new QueryWrapper<>();
        qw.eq("device_num",device_num);
        qw.last("limit 1");
        DeviceRange range = null;
        String key = "device_range_" + device_num;
        boolean blHasKey = redisTemplate.opsForHash().hasKey(key,key);
        if (blHasKey) {
            Object object = redisTemplate.opsForHash().get(key, key);
            String itemDicts = object != null ? object.toString() : "";
            if (StrUtil.isNotEmpty(itemDicts)) {
                JSONObject jsonObject = JSONUtil.parseObj(itemDicts);
                range = JSONUtil.toBean(JSONUtil.toJsonStr(jsonObject), DeviceRange.class);
            } else {
                range = deviceRangeDao.selectOne(qw);
                redisTemplate.opsForHash().put(key, key, JSONUtil.toJsonStr(range));
            }
        } else {
            range = deviceRangeDao.selectOne(qw);
            redisTemplate.opsForHash().put(key, key, JSONUtil.toJsonStr(range));
        }
        return range;
    }

    @Override
    public int resetDevice(DeviceRange device) {
        try{
            int ret = deviceRangeDao.updateById(device);
            if(ret > 0){
//                System.out.println("温湿度 保存成功：温度值" + device.getTemperature());
                QueryWrapper<DeviceRange> qw = new QueryWrapper<>();
                qw.eq("device_num",device.getDeviceNum());
                qw.last("limit 1");
                String key = "device_range_" + device.getDeviceNum();
                DeviceRange range = deviceRangeDao.selectOne(qw);
                redisTemplate.opsForHash().put(key, key, JSONUtil.toJsonStr(range));
            }
            return ret;
        }catch (Exception e){
            e.printStackTrace();
        }
        return 0;
    }
}
